#pragma once

#ifndef EVENT_LISTENER
#define EVENT_LISTENER

#include "EventHandler.h"

namespace cevent {

class EventListener
{
public:
	virtual ~EventListener(){
		DELETE(handler);
		EventController::GetInst().UnRegisterEventListener(this);
	};

protected:
	template <typename C, typename S, typename E>
	EventListener(E* event, C* caller, typename Handler<C, S>::Delegate del, S* sender){
		handler = new Handler<C, S>(caller, del, sender);
		EventController::GetInst().RegisterEventListener(event);
	};
	template <typename E, typename S>
	EventListener(E* event, typename HandlerDelStat<S>::DelegateStatic del, S* sender){
		handler = new HandlerDelStat<S>(del, sender);
		EventController::GetInst().RegisterEventListener(event);
	};

	void virtual Build() = 0;

	HandlerInterface* handler;
private:
	friend class findEventByEvent;
	friend class EventController;
	const EventRegistrator* eventRegistrator; // pointer to the static private field in EventController
	EventListener() {};
	EventListener(const EventListener&);  // undef
	void operator=(const EventListener&);  // undef
};

}

#define EVENT_AUTO_BUILD(x) \
template <typename C, typename S> \
x(C* caller, typename cevent::Handler<C, S>::Delegate del, S* sender) : EventListener(this, caller, del, sender){}; \
template <typename C> \
x(typename cevent::Handler<C, C>::Delegate del, C* sender) : EventListener(this, sender, del, sender){}; \
template <typename S> \
x(typename cevent::HandlerDelStat<S>::DelegateStatic del, S* sender) : EventListener(this, del, sender){}; \
virtual ~x(){};

#define NEW_EVENT_MAKER(x) \
class x : public cevent::EventListener \
{ \
public: \
	EVENT_AUTO_BUILD(x); \
	void Build() override{}; \
};

#endif